package main

import (
	"encoding/json"
	"fmt"
)

type Tree struct { // `json:"name"`就是struct tag 用于修改结构体字段名称，底层是映射方法
	Id       int    `json:"id"`
	Name     string `json:"name"`
	Age      int    `json:"age"`
	Children []Tree `json:"children"`
}

/*递归函数*/
func find(currentTree []Tree, name string) Tree { //tree []Tree, Ret *[]Tree
	//fmt.Println("currentTree=====>", currentTree)
	// 定义父层搜索，都找不到后，通过标记进入递归调用
	isFindFlag := false
	for _, v := range currentTree {
		if v.Name == name {
			fmt.Println("找到了====>", v)
			isFindFlag = true
			return v
		}
	}
	// 通过标记调用递归
	for _, v := range currentTree {
		if !isFindFlag {
			return find(v.Children, name)
		}
	}
	return Tree{}
}

func findTree(str string, name string) Tree {
	// 结构体赋值
	tree := &Tree{}
	err := json.Unmarshal([]byte(str), &tree)
	if err != nil {
		panic(err)
	}
	fmt.Println("*tree==>", *tree)
	if tree.Name == name {
		return *tree
	} else {
		return find(tree.Children, name)
	}
}

func main() {
	str :=
		`{
   "Id": 1 ,
   "Name":"lisi",
   "Age":60,
   "Children" :[
   {
      "Id":2,
      "Name":"wangwu",
      "Age":40,
      "Children":
      [
         {
            "Id":4,
            "Name":"xiaoming",
            "Age":15,
            "Children":
			[
				{
				  "Id":3,
				  "Name":"aaa",
				  "Age":42,
				  "Children":[]
   				},
				{
				  "Id":3,
				  "Name":"bbb",
				  "Age":42,
				  "Children":[]
   				}
			]
         }
      ]
   },
   {
      "Id":3,
      "Name":"zhangsan",
      "Age":42,
      "Children":[]
   },
{
      "Id":3,
      "Name":"ccc",
      "Age":42,
      "Children":[]
   }
]
}`
	// 先查清楚str类型是string 还是 Tree
	// 将string转成结构体，目标树放进函数中
	// 清楚结构体的查询方法，节点的遍历，匹配目标值条件与递归调用条件

	// 本题的递归退出条件是：先找出首个节点是否存在目标值，不存在则将[]True子节点传给递归函数进行递归，
	// 递归条件当上一个栈中所有节点都找不到目标值，再进行递归，
	// 推出条件是：最后一个节点的Children为空或者找不到目标值，则return Tree{}，否则递归继续调用查找，直到找到为止

	//如下有一颗家庭树，请通过递归单独找到所需人物的身份信息。（例：xiaoming）

	fmt.Println("result===>", findTree(str, "zhangsan"))
	//findTree(str, "xiaoming")

}
